package org.grc.app.z_project.z_framework.proxy;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 切面代理
 * 
 * @author grc
 * @since 1.0-SNAPSHOT
 */
public abstract class AspectProxy implements Proxy {

	private static final Logger LOGGER = LoggerFactory.getLogger(AspectProxy.class);
	
	/*
	 * 模板方法
	 */
	@Override
	public final Object doProxy(ProxyChain proxyChain) throws Throwable {
		Object result = null;
		
		Class<?> clazz = proxyChain.getTargetClass();
		Method method = proxyChain.getTargetMethod();
		Object[] params = proxyChain.getMethodParams();
		
		begin();
		try {
			// 方法过滤的关键？
			if (intercept(clazz, method, params)) {
				before(clazz, method, params);
				result = proxyChain.doProxyChain();
				after(clazz, method, params);
			} else {
				result = proxyChain.doProxyChain();
			}
		} catch (Exception e) {
			LOGGER.error("proxy failure", e);
			error(clazz, method, params);
			throw e;
		} finally {
			end();
		}
		
		return result;
	}

	public boolean intercept (Class<?> clazz, Method method, Object[] params) 
	throws Throwable {
		return true;
	}
	public void begin () {}

	public void before (Class<?> clazz, Method method, Object[] params) throws Throwable {}
	
	public void after (Class<?> clazz, Method method, Object[] params) throws Throwable {}
	
	public void error (Class<?> clazz, Method method, Object[] params) throws Throwable {}

	public void end () {}
}
